package com.ndkj.rpcserver.register;

import com.ndkj.rpcserver.common.dto.URL;

import java.io.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 分布式注册中心容器，只存储provider接口和机器信息
 */
public class MapRemoteRegister {

    /**
     * 注册中心的容器对象，URL代表一个可用的provider client
     * 为了支持provider集群注册，包装在容器对象
     */
    private static Map<String, List<URL>> map = new ConcurrentHashMap<>();

    public synchronized static void register(String interfaceName, String version, URL url) {
        List<URL> urls = map.get(interfaceName + version);
        if (urls == null) {
            urls = new ArrayList<>();
        }
        urls.add(url);
        map.put(interfaceName + version, urls);
        saveFile();
    }

    public static List<URL> get(String interfaceName, String version) {
        map = getFile();
        return map.get(interfaceName + version);
    }

    /**
     * 将map保存至文件中，得以支持多线程共享
     * 由于没有spring单例Bean的特性，当前一个map对象不能支持跨线程访问
     * 这里不能用单例模式实现共享，例如在Spring中的单例模式Bean被标注了@Scope("prototype")，依旧不能完成单例的任务
     */
    private synchronized static void saveFile() {
        try {
            String path = new File("").getAbsolutePath();
            FileOutputStream fileOutputStream = new FileOutputStream(path + "/register.txt");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(map);
        } catch (Exception e) {
            throw new RuntimeException("Save register.txt file exception");
        }
    }

    private synchronized static Map<String, List<URL>> getFile() {
        try {
            String path = new File("").getAbsolutePath();
            FileInputStream fileInputStream = new FileInputStream(path + "/register.txt");
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            return (Map<String, List<URL>>) objectInputStream.readObject();
        } catch (Exception e) {
            throw new RuntimeException("Read register.txt file exception");
        }
    }

}

